
<!-- 自定义组件 -->
<template>
    <el-card class="box-card">
        <div class="model-role">
            <!-- 搜索栏 表单组件 -->
            <el-form :inline="true" :model="queryForm" class="demo-form-inline">
                <el-form-item label="用户名称">
                    <el-input v-model="queryForm.username" placeholder="请输入用户名称" clearable>
                    </el-input>
                </el-form-item>
                <el-form-item>
                    <el-button @click="getDataList(1)">查询</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="openDialog">新增</el-button>
                </el-form-item>
            </el-form>
            <!-- 表格组件 -->
            <el-table :data="tableData" border style="width: 100%">
                <el-table-column type="selection" width="55"></el-table-column>
                <el-table-column prop="userId" label="ID" width="150"></el-table-column>
                <el-table-column prop="username" label="用户名称" width="180"> </el-table-column>
                <el-table-column prop="email" label="邮箱" width="200"> </el-table-column>
                <el-table-column prop="mobile" label="手机号" width="200"> </el-table-column>
                <el-table-column prop="status" label="状态" width="100">
                    <template slot-scope="scope">
                        <span>{{ scope.row.status == 1 ? "正常" : "禁用" }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="createUserId" label="创建者" width="200"> </el-table-column>
                <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
                <el-table-column label="操作">
                    <!-- 通过slot-scope="scope" 来获取当前行的索引 以及 行数据row -->
                    <template slot-scope="scope" width="180">
                        <el-button size="mini" type="primary" @click="openEdit(scope.$index, scope.row)">编辑</el-button>
                        <el-button size="mini" :type="scope.row.status === 1 ? 'danger' : 'success'"
                            @click="handleOnUse(scope.$index, scope.row)">
                            {{ scope.row.status === 1 ? "禁用" : "启用" }}
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页组件 -->
            <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" :current-page="pageIndex"
                :page-sizes="[5, 10, 20, 50, 100]" :page-size="pageSize" :total="totalCount"
                layout="total, sizes, prev, pager, next, jumper" style="margin-top:30px;">
            </el-pagination>
        </div>
        <el-dialog :title="dialogForm.userId == null ? '新增用户' : '编辑用户'" :visible.sync="dialogFormVisible" width="35%"
            :close-on-click-modal="false" @closed="closedDialog">
            <!-- 表单添加校验规则： 
                    1、<el-form>中添加属性:rules="rules" 
                    2、在data() return数据中定义rules：{}规则
                    3、输入框所在的<el-form-item>中添加属性prop="roleName",与rules：{roleName：[]}规则中的属性名roleName一致
                    4、<el-form>中添加属性ref="dialogForm" 
                    5、在提交方法中使用this.$refs["dialogForm"].validate()使校验生效
                     注意：前三步完成可以使输入框提示校验信息，但是不能阻拦提交函数的执行。需要4,5步才可以。
                     -->
            <el-form :model="dialogForm" :rules="rules" ref="dialogForm">
                <el-form-item label="用户名称" prop="username" label-width="90px">
                    <el-input v-model="dialogForm.username" placeholder="用户名称" autocomplete="off"
                        :disabled="dialogForm.userId != null"></el-input>
                </el-form-item>
                <el-form-item label="用户密码" prop="password" label-width="90px" v-if="dialogForm.userId === null">
                    <el-input v-model="dialogForm.password" placeholder="用户密码" autocomplete="off"
                        type="password"></el-input>
                </el-form-item>
                <el-form-item label="邮箱" prop="email" label-width="90px">
                    <el-input v-model="dialogForm.email" placeholder="邮箱" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="手机号" prop="mobile" label-width="90px">
                    <el-input v-model="dialogForm.mobile" placeholder="手机号" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="状态" prop="status" label-width="90px">
                    <!-- 下拉框方式选择状态
                        <el-select v-model="dialogForm.status" placeholder="请选择">
                        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
                        </el-option>
                    </el-select> -->
                    <!-- switch方式 选择状态 -->
                    <el-switch v-model="dialogForm.status" active-color="#13ce66" inactive-color="#ff4949" :active-value=1
                        :inactive-value=0 active-text="启用" inactive-text="禁用">
                    </el-switch>
                    <!-- <span> {{ dialogForm.status == 1 ? "启用" : "禁用" }}</span> -->
                </el-form-item>
                <el-form-item label="分配角色" prop="roleIds" label-width="90px">
                    <el-checkbox-group v-model="roleIds">
                        <el-checkbox v-for="item in allRoles" :key="item.roleId" :label="item.roleId">{{item.roleName}}</el-checkbox>
                    </el-checkbox-group>
                    <!-- {{ allRoles }} -->
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitDialog()">确 定</el-button>
            </div>
        </el-dialog>
    </el-card>
</template>

<script>
export default {
    name: 'sysUser',
    data() {
        /**
        * 自定义表单校验, 验证用户名称不可重复
        * @param {*} rule  规则对象
        * @param {*} value  输入的值
        * @param {*} callback  回调函数，方法出口
        */
        var repeatUserName = (rule, value, callback) => {
            console.log("表单校验：repeatUserName");
            if (this.dialogForm.userId != null) {
                // 更新用户，用户名不可修改，所以无需校验，直接放过
                callback();
            } else {
                // 新增用户
                // 用户名不可为空
                if (!value) {
                    callback(new Error('用户名不能为空！~'));
                } else {
                    //查询其他用户是否已经有重复的名称:是否存在用户名称，但不是当前的用户
                    this.$http.post("/sys/sysUser/existUserName", this.dialogForm).then((res) => {
                        //console.log("查询是否存在用户名称：", res);
                        if (res.data.data === true) {
                            //console.log("用户名查重")
                            callback(new Error('用户名称[' + value + ']已经存在，请换一个试试'));
                        } else {
                            callback();
                        }
                    }).catch(function (error) {
                        console.log(error);
                    })
                }
            }
        };
        //校验密码：编辑时：不可更新密码。 新增时：密码不能为空
        var checkPassword = (rule, value, callback) => {
            console.log("表单校验：checkPassword");
            if (this.dialogForm.userId != null) {
                // 更新 则直接放过
                callback();
            } else {
                // 新增 密码不能为空
                if (!value) {
                    callback(new Error('密码不能为空！~'));
                } else {
                    callback();
                }
            }
        };
        return {
            //查询的 表单数据
            queryForm: {
                username: ""
            },
            //表格数据
            tableData: [],
            pageIndex: 1,
            pageSize: 5,
            totalCount: 0,//总条数
            dataListLoading: false, //表格数据查询处理中，避免频繁重复点击
            /** dialog对话框 */
            dialogFormVisible: false, //dialog对话框打开状态
            dialogForm: {  //对话框表单数据
                userId: null,  // 给个默认值，为了后续好判断
                username: "",
                password: "",
                email: "",
                mobile: "",
                status: 1,
                //roleIds:[],  // 不知道为什么, <el-checkbox-group v-model="dialogForm.roleIds"> 其中 v-model不能指向dialogForm下面的roleIds会报错。 错误 TypeError: Cannot read properties of undefined (reading 'length')
            },
            roleIds:[],
            allRoles: [],
            //下拉框  启用状态下拉框数据
            // options: [{
            //     value: 1,
            //     label: '启用'
            // }, {
            //     value: 0,
            //     label: '禁用'
            // }],
            //【表单校验规则】添加用户
            rules: {
                username: [
                    //  trigger校验时机： blur：失去焦点
                    // { required: true, message: '请输入用户名称', trigger: 'blur' } //表单校验原生方式
                    { validator: repeatUserName, trigger: 'blur' } //自定义表单校验方式 需要定义一个变量repeatRoleNma 
                ],
                password: [
                    { validator: checkPassword, trigger: 'blur' }
                ],
                email: [
                    { required: true, message: '请输入邮箱', trigger: 'blur' }
                ],
                mobile: [
                    { required: true, message: '请输入手机号', trigger: 'blur' }
                ]
            }
        }

    },
    methods: {
        //查询事件
        getDataList(pageIndex) {
            /** 校验 重复操作 之后可以使用loading层解决*/
            if (this.dataListLoading) {
                //如果正在处理查询，则忽略本次点击
                return;
            }
            this.dataListLoading = true; //查询处理中
            /** 解决 页码虚高的问题  */
            //如果是点击查询按钮进来的，则从第一页开始查询，解决问题：之前查询了第n页数据，但是新输入的条件没有那么多数据，造成点击查询后显示第n页无数据的问题
            if (pageIndex) {
                this.pageIndex = pageIndex;
            }
            //声明params查询的参数
            const params = {
                pageIndex: this.pageIndex,
                pageSize: this.pageSize,
                username: this.queryForm.username
            };
            //debugger;
            //请求查询用户列表数据
            this.$http.get("/sys/sysUser/list", { params: params }).then((res) => {
                //console.log("查询用户,服务返回", res);
                this.tableData = res.data.data.list;  //表格数据
                this.totalCount = res.data.data.totalCount;  //总条数
            }).catch(function (error) {
                console.log(error);
            })
            this.dataListLoading = false; //查询处理结束
        },
        // 分页-切换页容量
        sizeChangeHandle(pageSize) {
            this.pageSize = pageSize; //切换 pageSize
            this.pageIndex = 1; //切换size后跳转到第一页
            this.getDataList(); //刷新表格数据
        },
        // 分页-跳转指定页码
        currentChangeHandle(pageIndex) {
            this.pageIndex = pageIndex; //跳转到指定页
            this.getDataList(); //刷新表格数据
        },
        //打开【添加用户】对话框
        openDialog() {
            this.$http.get("/sys/sysRole/listAll").then((res) => {
                console.log("/sysRole/listAll", res);
                //let sysUser = res.data.data;
                this.allRoles = res.data.data;
                //打开对话框
                this.dialogFormVisible = true; 
            }).catch(function (error) {
                console.log(error);
            })
        },
        //提交对话框 添加/编辑用户数据
        submitDialog() {
            //获取对应表单并校验通过才可以提交，否则无法提交
            this.$refs["dialogForm"].validate((valid) => {
                if (valid) {
                    //处理中，直接忽略点击事件，避免重复点击
                    if (this.submitAddLoading) {
                        return;
                    }
                    this.submitAddLoading = true; //开始处理
                    //执行提交请求
                    this.doSubmitAdd();
                    this.submitAddLoading = false; //结束处理
                } else {
                    //校验不通过
                    console.log('error submit!!');
                    return false;
                }
            });
        },
        //真正校验表单后的提交
        doSubmitAdd() {
            this.dialogForm.roleIds = this.roleIds;
            this.$http.post("/sys/sysUser/save", this.dialogForm).then((res) => {
                //console.log("保存账户,服务返回", res);
                this.dialogFormVisible = false; //关闭对话框
                this.getDataList(); //刷新表格当前页数据
            }).catch(function (error) {
                console.log(error);
            })
        },
        //打开用户编辑对话框
        openEdit(index, row) {
            // ※ 方法一： 不访问后台，直接回显页面表格的数据，数据不及时的弊端
            // this.dialogFormVisible = true; //打开对话框
            // // 回显对话框表单里的数据
            // this.dialogForm = {  //对话框表单数据
            //     userId: row.userId,  // 给个默认值，为了后续好判断
            //     username: row.username,
            //     //password: row.password, 隐藏密码
            //     email: row.email,
            //     mobile: row.mobile,
            //     status: row.status
            // };
            // ※ 方法二： 访问后台，回显数据库中最新的数据
            let params = new FormData();
            //alert(row.userId)
            params.append('userId', row.userId);
            this.$http.post("/sys/sysUser/queryUserById", params).then((res) => {
                console.log("通过id查询用户信息返回", res);
                let sysUser = res.data.data.sysUser;
                this.allRoles = res.data.data.sysRoles;
                this.roleIds = sysUser.roleIds; // 回显分配的角色
                //打开对话框
                this.dialogFormVisible = true;
                // 回显对话框表单里的数据
                this.dialogForm = {  //对话框表单数据
                    userId: sysUser.userId,
                    username: sysUser.username,
                    //password: res.data.data.password, 
                    email: sysUser.email,
                    mobile: sysUser.mobile,
                    status: sysUser.status
                };

            }).catch(function (error) {
                console.log(error);
            })
        },
        handleOnUse(index, row) {
            let params = {  //对话框表单数据
                userId: row.userId,  // 给个默认值，为了后续好判断
                status: (row.status + 1) % 2 // 1和0 切换
            }
            this.$http.post("/sys/sysUser/save", params).then((res) => {
                //console.log("保存账户,服务返回", res);
                this.dialogFormVisible = false; //关闭对话框
                this.getDataList(); //刷新表格当前页数据
            }).catch(function (error) {
                console.log(error);
            })
        },
        //监听对话框关闭事件，关闭后执行, 包括点击关闭+取消都会触发 
        closedDialog() {
            //console.log("监听关闭对话框，清除数据")
            //清除对话框表单中的数据
            this.dialogForm = {  //对话框表单数据
                userId: null,  // 给个默认值，为了后续好判断
                // username: "",  ※清空表单数据，这些属性可以省略赋值，默认为unfind
                // password: "",
                // email: "",
                // mobile: "",
                status: 1
            };
            // Element UI 自带清除表单方法
            //console.log("清空表单验证");
            this.$refs["dialogForm"].resetFields(); // 重置表单移除校验消息
            //扩展： this.$refs[formName].clearValidate(); // 仅清除验证
            this.roleIds = []; //清除分配的角色ID

        }
    }, 
    mounted() {
        this.getDataList();
    }
}
</script>